<?php

namespace app\base\model\goods;

use app\core\cache\{RedisCache, RedisKeys};
use app\core\log\Log4dd;
use app\base\model\system\SystemConfig;
use think\Model;
use think\Db;

class GoodsBaseInfo extends Model
{

    // 关闭自动写入时间戳
    protected $autoWriteTimestamp = false;

    protected $table = 'xy_goods.xy_goods_base_info';

    const DEFAULT_DATA = '1970-01-01 00:00:00';

    public function __construct($data = [])
    {
        parent::__construct($data);
        RedisCache::selectDB(config('redis_db_index.goods'));
    }

    public static function adminGetGoodsList($where = [], $order = [], $page_size = 20)
    {

        $field = 'gbi.goods_id,gbi.goods_category_id,gbi.goods_name,gbi.goods_title,gbi.goods_sub_title,gbi.goods_img_url,gbi.goods_specification,gbi.need_wish_coin,gbi.need_people,
        gbi.people_get_wish_coin,gbi.goods_stock,gbi.goods_label,gbi.goods_status,gbi.open_start_time,gbi.show_start_time,gbi.show_end_time,gbi.sort_num,gbi.create_time,
        gpi.platform_name,gpi.platform_price,gpi.platform_url,
        gsi.visit_num,gsi.initiate_num,gsi.success_num,
        gci.show_platform_price,gci.can_free';

        $query = self::alias('gbi')
            ->field($field)
            ->join('xy_goods.xy_goods_platform_info gpi', 'gbi.goods_id=gpi.goods_id', 'LEFT')
            //->join('xy_goods.xy_goods_keyword_info gki', 'gki.goods_id=gpi.goods_id', 'LEFT')
            ->join('xy_goods.xy_goods_statistics_info gsi', 'gsi.goods_id=gpi.goods_id', 'LEFT')
            ->join('xy_goods.xy_goods_config_info gci', 'gci.goods_id=gpi.goods_id', 'LEFT');


        if ($where) {
            $query->where($where);
        }

        if ($order) {
            $query->order($order);
        } else {
            $status_arr = implode(',', [1, 99, 0]);
            $query->orderRaw("field(gbi.goods_status,$status_arr)");
            $query->order("gbi.update_time", 'desc');
        }

        $items = $query->paginate($page_size)->toArray();

        if ($items && !empty($items['data'])) {
            foreach ($items['data'] as &$item) {
                $item['introduce_content_info'] = GoodsIntroduceInfo::where('goods_id', $item['goods_id'])
                    ->where('introduce_type', GoodsIntroduceInfo::INTRODUCE_TYPE_CONTENT)->where('status', 1)->order('sort_num', 'asc')->column('introduce_url');
                $item['introduce_carousel_info'] = GoodsIntroduceInfo::where('goods_id', $item['goods_id'])
                    ->where('introduce_type', GoodsIntroduceInfo::INTRODUCE_TYPE_CAROUSEL)->where('status', 1)->order('sort_num', 'asc')->column('introduce_url');
                self::checkNum($item);
            }
        }

        return $items;

    }

    public static function apiGetGoodsList($page, $page_size = 15)
    {

        $key = RedisKeys::getGoodsListKey($page);

        $items = RedisCache::get($key);

        if ($items) {
            return json_decode($items, true);
        }

        $where_arr = self::buildWhere(['gb.goods_stock' => ['>=', 0]]);
        $mode = SystemConfig::getSystemConfigByName('goods_list_sort_mode', 0);

        $query = self::alias('gb')
            ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->join('xy_goods.xy_goods_config_info gci', 'gb.goods_id=gci.goods_id', 'LEFT')
            ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.goods_specification,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_label,gb.goods_status,gp.platform_name,platform_price,gci.show_platform_price,gci.can_free')
            ->where($where_arr['where'])
            ->where($where_arr['open_start_time'])
            ->where($where_arr['show_start_time'])
            ->where($where_arr['show_end_time']);

        if ($mode == 1) {
            $query->order('gb.sort_num', 'asc');
        } else {
            $query->join('xy_goods.xy_goods_statistics_info gs', 'gb.goods_id=gs.goods_id', 'LEFT');
            $query->order('gb.need_wish_coin', 'asc');
            $query->order('gs.visit_num', 'desc');
        }
        $items = $query->paginate([
            'page' => $page,
            'list_rows' => $page_size
        ])->toArray();

        //需要处理成不带0的，mysql死活处理不成
        if ($items && !empty($items['data'])) {
            array_walk($items['data'], function (&$item) {
                self::checkNum($item);
            });
            RedisCache::set($key, json_encode($items), 600);
        }

        return $items;

    }

    public static function delApiGoodsListCache()
    {
        //$keys = RedisCache::keys(RedisKeys::getGoodsListPrefixKey() . '*');
        $keys = [];
        for ($i = 1; $i <= 10; $i++) {
            $keys[] = RedisKeys::getGoodsListKey($i);
        }
        Log4dd::info('删除商品列表缓存', ['keys' => $keys]);
        if ($keys && is_array($keys)) {
            RedisCache::pipeline();
            foreach ($keys as $key) {
                RedisCache::del($key);
            }
            RedisCache::exec();
        }
    }

    public static function getGoodsBaseInfo($goods_id, $fields = [])
    {
        $key = RedisKeys::getGoodsInfoKey($goods_id);
        if (!RedisCache::hexists($key, 'goods_id')) {
            $query = self::alias('gb')
                ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
                ->join('xy_goods.xy_goods_config_info gci', 'gb.goods_id=gci.goods_id', 'LEFT')
                ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_specification,gb.goods_label,gb.goods_stock,gb.goods_status,gb.open_start_time,gb.show_start_time,gb.show_end_time,gp.platform_name,gp.platform_price,gci.show_platform_price,gci.can_free');

            $query->where('gb.goods_id', $goods_id);
            $info = $query->find();

            if ($info) {
                $info = $info->toArray();
                self::checkNum($info);
                RedisCache::hMset($key, $info);
                return $info;
            }
        }

        if (!empty($fields)) {
            return RedisCache::hMGet($key, $fields);
        } else {
            return RedisCache::hGetAll($key);
        }
    }

    public static function getGoodsBaseInfoByField($goods_id, $field)
    {
        $key = RedisKeys::getGoodsInfoKey($goods_id);
        if (!RedisCache::hexists($key, $field)) {
            $row = self::getGoodsBaseInfo($goods_id);
            return $row[$field] ?? '';
        } else {
            return RedisCache::hget($key, $field);
        }
    }

    public static function delGoodsInfoCache($goods_id)
    {
        RedisCache::del(RedisKeys::getGoodsInfoKey($goods_id));
        return GoodsBaseInfo::getGoodsBaseInfo($goods_id);
    }

    public static function getMultipleGoodsBaseInfo($goods_ids)
    {
        $query = self::alias('gb')
            ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_status,gb.show_start_time,gb.show_end_time,gp.platform_name,gp.platform_price');

        $query->whereIn('gb.goods_id', $goods_ids);

        $items = $query->select();

        if($items){
            array_walk($items, function (&$item) {
                self::checkNum($item);
            });
        }

        return $items;
    }

    public static function checkNum(&$item)
    {
        isset($item['need_wish_coin']) && ($item['need_wish_coin'] = (float)$item['need_wish_coin']);
        isset($item['people_get_wish_coin']) && ($item['people_get_wish_coin'] = (float)$item['people_get_wish_coin']);
        isset($item['platform_price']) && ($item['platform_price'] = (float)$item['platform_price']);
    }

    public static function buildWhere($where = [], $unWhere = [])
    {
        $base_where = [
            'gb.need_wish_coin' => ['>', 0],
            'gb.need_people' => ['>', 0],
            'gb.people_get_wish_coin' => ['>', 0],
            'gb.goods_stock' => ['>', 0],
            'gb.goods_status' => ['>', 0],
            'gp.platform_price' => ['>', 0],
        ];

        $where = array_merge($base_where, $where);

        if ($unWhere) {
            foreach ($unWhere as $un) {
                unset($where[$un]);
            }
        }

        $open_start_time = "(gb.open_start_time = '" . self::DEFAULT_DATA . "' or ( gb.open_start_time <> '" . self::DEFAULT_DATA . "' and gb.open_start_time < '" . date('Y-m-d H:i:s',
                strtotime('-3 days')) . "'))";

        $show_start_time = "(gb.show_start_time = '" . self::DEFAULT_DATA . "' or ( gb.show_start_time <> '" . self::DEFAULT_DATA . "' and gb.show_start_time < '" . date('Y-m-d H:i:s') . "'))";


        $show_end_time = "(gb.show_end_time = '" . self::DEFAULT_DATA . "' or ( gb.show_end_time <> '" . self::DEFAULT_DATA . "' and gb.show_end_time > '" . date('Y-m-d H:i:s') . "'))";


        return compact('where', 'open_start_time', 'show_start_time', 'show_end_time');

    }


    /**
     * Desc: 根据心愿值获取可以发起的商品列表
     * Date: 2020/1/31 16:23
     * Author: yiyu
     * @param $my_wish_coin_num
     * @param $num
     * @return false|\PDOStatement|string|\think\Collection
     */
    public static function getCanInitiateGoodsListBWishNum($my_wish_coin_num, $num)
    {

        $where_arr = self::buildWhere(['gb.need_wish_coin' => ['<=', $my_wish_coin_num]]);
        $items = self::alias('gb')
            ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_status,gp.platform_name,gp.platform_price')
            ->where($where_arr['where'])
            ->where($where_arr['open_start_time'])
            ->where($where_arr['show_start_time'])
            ->where($where_arr['show_end_time'])
            ->order('gb.sort_num', 'desc')
            ->limit($num)
            ->select();

        if($items){
            array_walk($items, function (&$item) {
                self::checkNum($item);
            });
        }

        return $items;
    }


    public static function getRecommendGoodsIds($where = [])
    {

        $where_arr = self::buildWhere();

        if ($where) {
            $where = array_merge($where_arr['where'], $where);
        }

        $ids = self::alias('gb')->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->where($where)
            ->where($where_arr['open_start_time'])
            ->where($where_arr['show_start_time'])
            ->where($where_arr['show_end_time'])
            ->column('gb.goods_id');

        Log4dd::info('获取推荐数据', $ids);

        return $ids;
    }


    public static function getOneGoodsByWishValue($wish_value)
    {
        $where_arr = self::buildWhere(['gb.need_wish_coin' => ['<=', $wish_value]]);
        $goods_info = self::alias('gb')
            ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->join('xy_goods.xy_goods_statistics_info gs', 'gb.goods_id=gs.goods_id', 'LEFT')
            ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.goods_specification,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_label,gb.goods_status,gp.platform_name,gp.platform_price')
            ->where($where_arr['where'])
            ->where($where_arr['open_start_time'])
            ->where($where_arr['show_start_time'])
            ->where($where_arr['show_end_time'])
            //->orderRaw('abs(' . $wish_value. ' - `gb`.`need_wish_coin`)')
            ->order('gb.need_wish_coin', 'desc')
            ->order('gs.visit_num', 'desc')
            ->find();

        if (empty($goods_info)) {
            $where_arr['where']['gb.need_wish_coin'] = ['>', $wish_value];
            $goods_info = self::alias('gb')
                ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
                ->join('xy_goods.xy_goods_statistics_info gs', 'gb.goods_id=gs.goods_id', 'LEFT')
                ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.goods_specification,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_label,gb.goods_status,gp.platform_name,gp.platform_price')
                ->where($where_arr['where'])
                ->where($where_arr['open_start_time'])
                ->where($where_arr['show_start_time'])
                ->where($where_arr['show_end_time'])
                ->order('gb.need_wish_coin', 'asc')
                ->order('gs.visit_num', 'desc')
                ->find();
        }

        Log4dd::info('获取单个推荐的商品信息', [$wish_value, $goods_info]);

        if($goods_info){
            self::checkNum($goods_info);
        }

        return $goods_info;
    }

    public static function getMultipleGoodsByWishValue($wish_value, $limit = 3)
    {
        $where_arr = self::buildWhere(['gb.need_wish_coin' => ['<=', $wish_value]]);
        Log4dd::info('获取多个推荐的商品信息1', $where_arr);
        $gt_items = [];
        $lt_items = self::alias('gb')
            ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
            ->join('xy_goods.xy_goods_statistics_info gs', 'gb.goods_id=gs.goods_id', 'LEFT')
            ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.goods_specification,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_label,gb.goods_status,gp.platform_name,gp.platform_price')
            ->where($where_arr['where'])
            ->where($where_arr['open_start_time'])
            ->where($where_arr['show_start_time'])
            ->where($where_arr['show_end_time'])
            ->order('gb.need_wish_coin', 'desc')
            ->order('gs.visit_num', 'desc')
            ->limit($limit)
            ->select();

        $limit = $limit - count($lt_items);

        if ($limit > 0) {
            $where_arr['where']['gb.need_wish_coin'] = ['>', $wish_value];
            Log4dd::info('获取多个推荐的商品信息2', $where_arr);
            $gt_items = self::alias('gb')
                ->join('xy_goods.xy_goods_platform_info gp', 'gb.goods_id=gp.goods_id', 'INNER')
                ->join('xy_goods.xy_goods_statistics_info gs', 'gb.goods_id=gs.goods_id', 'LEFT')
                ->field('gb.goods_id,gb.goods_category_id,gb.goods_name,gb.goods_title,gb.goods_sub_title,gb.goods_img_url,gb.goods_specification,gb.need_wish_coin,
            gb.need_people,gb.people_get_wish_coin,gb.goods_stock,gb.goods_label,gb.goods_status,gp.platform_name,gp.platform_price')
                ->where($where_arr['where'])
                ->where($where_arr['open_start_time'])
                ->where($where_arr['show_start_time'])
                ->where($where_arr['show_end_time'])
                ->order('gb.need_wish_coin', 'asc')
                ->order('gs.visit_num', 'desc')
                ->limit($limit)
                ->select();
        }

        $items = array_merge($lt_items, $gt_items);

        Log4dd::info('获取多个推荐的商品信息', [$wish_value, $items]);

        $sorts = [];

        if($items){
            array_walk($items, function (&$item) use (&$sorts) {
                self::checkNum($item);
                $sorts[] = $item['need_wish_coin'];
            });

            array_multisort($sorts, SORT_ASC, $items);
        }

        return $items;
    }


}